home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / tools / amigaos4_only / fracblank / source / fraccommodity.c < prev    next >
C/C++ Source or Header  |  2004-08-03  |  10KB  |  369 lines

  1. /*
  2. **  FracBlank - AmigaDOS 2.04 commodities utility screenblanker
  3. **
  4. **  Copyright © 1991-1995 by Olaf `Olsen' Barthel
  5. **    All Rights Reserved
  6. **
  7. **  Cosmic flame fractal code derived from xlock source code
  8. **
  9. **  Copyright © 1988-1991 by Patrick J. Naughton.
  10. */
  11.  
  12. #include <dos/dos.h>
  13.  
  14. #include <libraries/commodities.h>
  15.  
  16. #include <proto/commodities.h>
  17. #include <proto/datatypes.h>
  18. #include <proto/dos.h>
  19. #include <proto/exec.h>
  20.  
  21. #include "Frac.h"
  22. #include "FracCommodity.h"
  23.  
  24. // Commodities interface data
  25.  
  26. struct MsgPort *CxPort;
  27. CxObj          *Broker;
  28. ULONG           SpecialQualifier;
  29.  
  30. // A new broker definition, Commodities needs this
  31.  
  32. struct NewBroker NewBroker = {
  33.   NB_VERSION,
  34.   "FracBlank",
  35.   "Fractal screen blanker v2.3",
  36.   "Screen blanker",
  37.   NBU_NOTIFY | NBU_UNIQUE,
  38.   COF_SHOW_HIDE,
  39.   0,
  40.   NULL,
  41.   0
  42. };
  43.  
  44. // Key sequence buffers
  45.  
  46. UBYTE HotkeyBuffer[256],
  47.       BlankScreenBuffer[256],
  48.       SaveScreenBuffer[256];
  49.  
  50. /* CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID):
  51.  *
  52.  *  A replacement for the HotKey() routine found in
  53.  *  amiga.lib.
  54.  */
  55.  
  56. CxObj *CustomHotKey(STRPTR Code, struct MsgPort *Port, LONG ID) {
  57.  
  58.   CxObj *Filter;
  59.  
  60.   if (Filter = ICommodities->CxFilter(Code)) {
  61.     CxObj *Sender;
  62.     if (Sender = ICommodities->CxSender(Port,ID)) {
  63.       CxObj *Translator;
  64.       ICommodities->AttachCxObj(Filter,Sender);
  65.       if (Translator = ICommodities->CxTranslate(NULL)) {
  66.         ICommodities->AttachCxObj(Filter,Translator);
  67.         if (!ICommodities->CxObjError(Filter)) return(Filter);
  68.       }
  69.     }
  70.     ICommodities->DeleteCxObjAll(Filter);
  71.   }
  72.  
  73.   return(NULL);
  74.  
  75. }
  76.  
  77. /* BlankerAction(CxMsg *CxMessage,CxObj *CxObject):
  78.  *
  79.  *  Commodities support routine, handles the Commodities
  80.  *  custom actions (in this case: filter the InputEvents
  81.  *  coming in and enable/disable the screen blanker).
  82.  */
  83.  
  84. VOID BlankerAction(CxMsg *CxMessage, CxObj *CxObject) {
  85.  
  86.   static BYTE Count = 0;
  87.  
  88.   struct InputEvent *Event = (struct InputEvent *)ICommodities->CxMsgData(CxMessage);
  89.  
  90.   // Push the blanker screen to the front if necessary
  91.  
  92.   IExec->ObtainSemaphoreShared(&BlankSemaphore);
  93.  
  94.   if (BlankScreen) IExec->Signal((struct Task *)BlankerControlProcess,SIG_REFRESH);
  95.  
  96.   IExec->ReleaseSemaphore(&BlankSemaphore);
  97.  
  98.   // This looks like a timer event
  99.  
  100.   if (Event->ie_Class == IECLASS_TIMER) {
  101. //  if (!Window) {
  102.     if (TRUE) {
  103.       // Screen blanker still inactive?
  104.       IExec->ObtainSemaphoreShared(&BlankSemaphore);
  105.       if (!BlankTask) {
  106.         // Is there a timeout to take care of?
  107. //      if (ScreenTimeout && !Window) {
  108.         if (ScreenTimeout && TRUE) {
  109.           // Are we ready to create the
  110.           // screenblanker?
  111.           if (ScreenCount++ >= ScreenTimeout * 10) IExec->Signal((struct Task *)BlankerControlProcess,SIG_START);
  112.         }
  113.       }
  114.       else {
  115.         // Every 5/10 second we signal the blanker
  116.         // task to rotate the palette.
  117.         if (ColourMode == COLOUR_CYCLE) {
  118.           if (Count++ >= 2) {
  119.             IExec->Signal(BlankTask,CycleMask);
  120.             Count = 0;
  121.           }
  122.         }
  123.         // Is it time to change the pattern?
  124.         if (PatternTimeout) {
  125.           if (PatternCount++ >= PatternTimeout * 10) {
  126.             IExec->Signal((struct Task *)BlankerControlProcess,SIG_CHANGE);
  127.             PatternCount = 0;
  128.           }
  129.         }
  130.       }
  131.       IExec->ReleaseSemaphore(&BlankSemaphore);
  132.     }
  133.   }
  134.   else {
  135.     // The following lines determine whether
  136.     // the blanker is to be removed or to
  137.     // be left running.
  138.     switch(Event->ie_Class) {
  139.       case IECLASS_RAWKEY:
  140.         if (!(Event->ie_Code & IECODE_UP_PREFIX) && !(Event->ie_Qualifier & SpecialQualifier)) IExec->Signal((struct Task *)BlankerControlProcess,SIG_BREAK);
  141.         break;
  142.       case IECLASS_NEWPOINTERPOS:
  143.       case IECLASS_POINTERPOS:
  144.       case IECLASS_RAWMOUSE:
  145.         IExec->Signal((struct Task *)BlankerControlProcess,SIG_BREAK);
  146.         break;
  147.     }
  148.     ScreenCount = 0;
  149.   }
  150.  
  151. }
  152.  
  153. /* ShutdownCx():
  154.  *
  155.  *  Close the Commodities interface.
  156.  */
  157.  
  158. VOID ShutdownCx() {
  159.  
  160.   if (CxPort) {
  161.     struct Message *Message;
  162.     // Remove the broker
  163.     if (Broker) ICommodities->DeleteCxObjAll(Broker);
  164.     // Remove the MsgPort from the public list
  165.     IExec->RemPort(CxPort);
  166.     // Remove all pending messages
  167.     while(Message = IExec->GetMsg(CxPort)) IExec->ReplyMsg(Message);
  168.     // Delete the MsgPort
  169.     IExec->DeleteMsgPort(CxPort);
  170.     CxPort = NULL;
  171.     Broker = NULL;
  172.   }
  173.  
  174. }
  175.  
  176. /* SetupCx():
  177.  *
  178.  *  Set up the Commodities interface.
  179.  */
  180.  
  181. LONG SetupCx() {
  182.  
  183.   LONG Error;
  184.  
  185.   // Cancel any previously made assignments
  186.  
  187.   ShutdownCx();
  188.  
  189.   // Create a reply port
  190.  
  191.   if (CxPort = IExec->CreateMsgPort()) {
  192.     // Fill in a unique name
  193.     CxPort->mp_Node.ln_Name = NewBroker.nb_Name;
  194.     // Add the reply port to the public list
  195.     IExec->AddPort(CxPort);
  196.     // Install the replyport
  197.     NewBroker.nb_Port = CxPort;
  198.     // Create the broker
  199.     if (Broker = ICommodities->CxBroker(&NewBroker,&Error)) {
  200.       CxObj *ObjectList;
  201.       // Link the hotkeys
  202.       ICommodities->AttachCxObj(Broker,CustomHotKey(HotkeyBuffer,      CxPort,POP_WINDOW));
  203.       ICommodities->AttachCxObj(Broker,CustomHotKey(BlankScreenBuffer, CxPort,BLANK_SCREEN));
  204.       ICommodities->AttachCxObj(Broker,CustomHotKey(SaveScreenBuffer,  CxPort,SAVE_SCREEN));
  205.       // Install the plain InputEvent handler
  206.       ObjectList = ICommodities->CxCustom(BlankerAction,NULL);
  207.       // Any accumulated errors?
  208.       if (!(Error = ICommodities->CxObjError(ObjectList))) {
  209.         // Add the custom object
  210.         ICommodities->AttachCxObj(Broker,ObjectList);
  211.         // Any errors?
  212.         if (!(Error = ICommodities->CxObjError(Broker))) {
  213.           // Activate the broker
  214.           ICommodities->ActivateCxObj(Broker,TRUE);
  215.           return(0);
  216.         }
  217.       }
  218.       if (Error & COERR_BADFILTER) Error = ERR_BadFilter;
  219.       else {
  220.         if (Error & COERR_BADTYPE) Error = ERR_BadType;
  221.         else Error = ERROR_NO_FREE_STORE;
  222.       }
  223.     }
  224.     else Error = Error - CBERR_SYSERR + ERR_SystemError;
  225.   }
  226.   else Error = ERR_NoMsgPort;
  227.  
  228.   ShutdownCx();
  229.  
  230.   return(Error);
  231.  
  232. }
  233.  
  234. /* HandleCxMsg(CxMsg *Message):
  235.  *
  236.  *  Handle incoming Commodities messages.
  237.  */
  238.  
  239. VOID HandleCxMsg(CxMsg *Message) {
  240.  
  241.   ULONG MessageID   = ICommodities->CxMsgID(Message),
  242.         MessageType = ICommodities->CxMsgType(Message);
  243.  
  244.   IExec->ReplyMsg((struct Message *)Message);
  245.  
  246.   // Take a look at the message type
  247.  
  248.   switch(MessageType) {
  249.     // It's a hotkey
  250.     case CXM_IEVENT:
  251.       switch(MessageID) {
  252.         // Create the control panel
  253.         case POP_WINDOW:
  254.           // Make sure the blanker has terminated
  255.           IExec->Signal((struct Task *)BlankerControlProcess,SIG_BREAK);
  256. //        SetupWindow();
  257.           break;
  258.           // Blank the screen
  259.         case BLANK_SCREEN:
  260. //        if (!Window) {
  261.           if (TRUE) {
  262.             IExec->ObtainSemaphoreShared(&BlankSemaphore);
  263.             if (!BlankTask) IExec->Signal((struct Task *)BlankerControlProcess,SIG_START);
  264.             else {
  265.               IExec->Signal((struct Task *)BlankerControlProcess,SIG_CHANGE);
  266.               PatternCount = 0;
  267.             }
  268.             IExec->ReleaseSemaphore(&BlankSemaphore);
  269.           }
  270.           break;
  271.         // Save the screen in the clipboard
  272.         case SAVE_SCREEN:
  273.           if (DataTypesBase) {
  274.             IExec->ObtainSemaphoreShared(&BlankSemaphore);
  275.             // Let the background process handle the job
  276.             if (BlankScreen && !Saver) {
  277.               IDOS->CreateNewProcTags(NP_Name,      "« FracBlank Screen Saver »",
  278.                                       NP_Entry,     SaverEntry,
  279.                                       NP_StackSize, 4096,
  280.                                       NP_WindowPtr, -1,
  281.                                       TAG_DONE);
  282.             }
  283.             IExec->ReleaseSemaphore(&BlankSemaphore);
  284.           }
  285.           break;
  286.       }
  287.       break;
  288.     // It's an internal Commodities command
  289.     case CXM_COMMAND:
  290.       switch(MessageID) {
  291.         // Disable the Commodity
  292.         case CXCMD_DISABLE:
  293.           ICommodities->ActivateCxObj(Broker,FALSE);
  294.           break;
  295.         // Enable the Commodity
  296.         case CXCMD_ENABLE:
  297.           ICommodities->ActivateCxObj(Broker,TRUE);
  298.           break;
  299.         // Create the control panel
  300.         case CXCMD_APPEAR:
  301.         case CXCMD_UNIQUE:
  302. //        SetupWindow();
  303.           break;
  304.         // Close the control panel
  305.         case CXCMD_DISAPPEAR:
  306. //        ShutdownWindow();
  307.           break;
  308.         // Remove this Commodity
  309.         case CXCMD_KILL:
  310.           CloseAll(RETURN_OK);
  311.           break;
  312.       }
  313.       break;
  314.   }
  315.  
  316. }
  317.  
  318. /* BuildMask(STRPTR Code):
  319.  *
  320.  *  Build a mask of qualifiers covered by the given
  321.  *  code.
  322.  */
  323.  
  324. ULONG BuildMask(STRPTR Code) {
  325.  
  326.   IX Expression;
  327.  
  328.   if (!ICommodities->ParseIX(Code,&Expression)) {
  329.     ULONG Mask = 0,
  330.           Bits = Expression.ix_Qualifier & Expression.ix_QualMask;
  331.     // Are shift/caps lock keys involved?
  332.     if (Bits & IXSYM_CAPSMASK) {
  333.       // Are both shift keys equivalent?
  334.       if (Expression.ix_QualSame & IXSYM_SHIFT) Mask |= IXSYM_SHIFTMASK | (Bits & IEQUALIFIER_CAPSLOCK);
  335.       else {
  336.         // Are all shift/caps lock keys equivalent?
  337.         if (Expression.ix_QualSame & IXSYM_CAPS) Mask |= IXSYM_CAPSMASK;
  338.         else Mask |= Bits & IXSYM_CAPSMASK;
  339.       }
  340.     }
  341.     // Are alt keys involved?
  342.     if (Bits & IXSYM_ALTMASK) {
  343.       // Are both alt keys equivalent?
  344.       if (Expression.ix_QualSame & IXSYM_ALT) Mask |= IXSYM_ALTMASK;
  345.       else Mask |= Bits & IXSYM_ALTMASK;
  346.     }
  347.     // Take care of the remaining qualifiers
  348.     Mask |= Bits & ~(IXSYM_ALTMASK | IXSYM_CAPSMASK);
  349.     return(Mask);
  350.   }
  351.   else return(0);
  352.  
  353. }
  354.  
  355. /* AddQualifier(STRPTR Code,ULONG Qualifier):
  356.  *
  357.  *  Add to the qualifier mask.
  358.  */
  359.  
  360. ULONG AddQualifier(STRPTR Code,ULONG Qualifier) { return(Qualifier | BuildMask(Code)); }
  361.  
  362. /* SubQualifier(STRPTR Code,ULONG Qualifier):
  363.  *
  364.  *  Remove keys from the qualifier mask.
  365.  */
  366.  
  367. ULONG SubQualifier(STRPTR Code,ULONG Qualifier) { return(Qualifier & ~BuildMask(Code)); }
  368.  
  369.